/*
 * Copyright 2008 FBK (http://www.fbk.eu/)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.fbk.it.hlt.jlsi;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.log4j.Logger;

/**
 * to do
 * 
 * @author Claudio Giuliano
 * @version %I%, %G%
 * @since 1.0
 */
public class ScoreTermMap {
	/**
	 * Define a static logger variable so that it references the Logger instance
	 * named <code>ScoreTermMap</code>.
	 */
	static Logger logger = Logger.getLogger(ScoreTermMap.class.getName());

	/**
	 * to do.
	 */
	private SortedMap map;

	//
	private String term;

	//
	private int size;

	//
	private DecimalFormat formatter;

	private int dimensione;
	/**
	 * Constructs a <code>ScoreTermMap</code> object.
	 */
	public ScoreTermMap(String term, int size) {
		formatter = new DecimalFormat("0.000");

		this.term = term;
		this.size = size;
		this.dimensione=0;
		map = new TreeMap(new ScoreComparator());
	} // end constructor

	/**
	 * Add a token to the index ScoreTermMap
	 * 
	 * @param token
	 *            the token.
	 */
	public void put(double score, String term) {
		// logger.debug(score + " " + term);
		Double key = Math.abs(score);
		List tlist = (List) map.get(key);

		if (tlist == null) {
			tlist = new ArrayList();
			tlist.add(term);
			map.put(key, tlist);
		} else {
			tlist.add(term);
		}
		dimensione++;
	} // end put
	public void put_old(double score, String term) {
		// logger.debug(score + " " + term);
		Double key = new Double(score);
		List tlist = (List) map.get(key);

		if (tlist == null) {
			tlist = new ArrayList();
			tlist.add(term);
			map.put(key, tlist);
		} else {
			tlist.add(term);
		}
	}
	/*
	 * public List get(String term) { Double key = new Double(score);
	 * logger.debug(key); return (List) map.get(key); } // end get
	 */

	/**
	 * Returns a <code>String</code> object representing this <code>Word</code>.
	 * 
	 * @return a string representation of this object.
	 */
	public String toString() {
		StringBuffer sb = new StringBuffer();

		String[] s = term.split("_");

		// Set set = entityMap.get(s[0]);

		// String label = null;
		// if (set.iterator().hasNext())
		// label = (String) set.iterator().next();

		sb.append(term);
		// sb.append(" ");
		// sb.append(set);
		sb.append("\n");

		int count = 0;
		int tcount = 0;
		int ocount = 0;
		int lcount = 0;
		Iterator it = map.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry me = (Map.Entry) it.next();
			sb.append(formatter.format(me.getKey()));
			sb.append("\t");

			List tlist = (List) me.getValue();
			for (int i = 0; i < tlist.size(); i++) {
				if (i != 0) {
					// sb.append(", ");
					sb.append("\n");
					sb.append(formatter.format(me.getKey()));
					sb.append("\t");
				}

				String t = (String) tlist.get(i).toString();
				tcount++;

				s = t.split("_");
				/*
				 * set = entityMap.get(s[0]); if ((set.size() == 1) &&
				 * (set.contains("O"))) ocount++; else if (set.contains(label))
				 * lcount++;
				 */
				sb.append(tlist.get(i));
				// sb.append(" ");
				// sb.append(set);
			}
			sb.append("\n");
			count++;

			if (count > size)
				break;
		}

		/*
		 * DecimalFormat formatter = new DecimalFormat("##.#");
		 * 
		 * sb.append("entities count " + tcount); sb.append("\n");
		 * sb.append(label + " count " + lcount + " " +
		 * formatter.format((double) lcount / tcount * 100) + "%");
		 * sb.append("\n"); sb.append("O count " + ocount + " " +
		 * formatter.format((double) ocount / tcount * 100) + "%");
		 * sb.append("\n");
		 */
		return sb.toString();
	} // end toString

	public Percentili[] toPercentili(){
		Percentili[] p = new Percentili[100];
		for (int i =0; i<100;i++){
			p[i]=new Percentili();
		}
		Iterator it = map.entrySet().iterator();
	int dim = dimensione / 100;
	int count =0;
	int index =0;
	int j=0;
	while (it.hasNext()) {
		Map.Entry me = (Map.Entry) it.next();
		List tlist = (List) me.getValue();
		for (int i = 0; i < tlist.size(); i++) {
			p[index].add((Double) me.getKey(),tlist.get(i).toString());
			j++;
			if (j>dim)
			{
				index++;
				j=0;
			}		
		}
		count++;

		if (count > size)
			break;
	}

	/*
	 * DecimalFormat formatter = new DecimalFormat("##.#");
	 * 
	 * sb.append("entities count " + tcount); sb.append("\n");
	 * sb.append(label + " count " + lcount + " " +
	 * formatter.format((double) lcount / tcount * 100) + "%");
	 * sb.append("\n"); sb.append("O count " + ocount + " " +
	 * formatter.format((double) ocount / tcount * 100) + "%");
	 * sb.append("\n");
	 */
	return p;
} // end toString
	
	
	
	
	//
	public Set entrySet() {
		return map.entrySet();
	} // end entrySet

	//
	private class ScoreComparator implements Comparator {
		//
		public int compare(Object o1, Object o2) {
			Double d1 = (Double) o1;
			Double d2 = (Double) o2;
			double diff = d1.doubleValue() - d2.doubleValue();

			if (diff == 0)
				return 0;
			else if (diff < 0)
				return 1;

			return -1;
			// logger.debug(d1 + " - " + d2 + " = " + (int) (d1.doubleValue() -
			// d2.doubleValue()));

		} // end compare

		//
		public boolean equals(Object obj) {
			return this == obj;
		} // end equals
	} // end class ScoreComparator

} // end class ScoreTermMap